package com.yuanluludev.lib_base.base

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Bundle
import android.util.SparseArray
import android.view.MotionEvent
import android.view.View
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import com.gyf.immersionbar.ImmersionBar
import com.yuanluludev.lib_base.R
import com.yuanluludev.lib_base.action.ActivityAction
import com.yuanluludev.lib_base.action.BundleAction
import com.yuanluludev.lib_base.action.ClickAction
import com.yuanluludev.lib_base.action.KeyboardAction
import com.yuanluludev.lib_base.widget.LoadingDialogFragment
import com.yuanluludev.lib_base.widget.TitleBarView
import java.util.*
import kotlin.math.pow

/**
 * yuanLuLu
 * Activity基类，要求所有的Activity继承此类
 */
abstract class BaseActivity : AppCompatActivity(),
    ClickAction, BundleAction, ActivityAction, KeyboardAction {

    /**
     * 是否需要使用DataBinding 供子类BaseVmDbActivity修改，用户请慎动
     */
    private var isUseDB = false

    private lateinit var loadingDialogFragment: LoadingDialogFragment

    /** Activity 回调集合 */
    private val activityCallbacks: SparseArray<OnActivityCallback?> by lazy { SparseArray(1) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        beforeLoadLayout()

        if (!isUseDB) {
            setContentView(getLayoutResId())
        } else {
            initViewModel()
            initDataBinding()
        }

        afterLoadLayout(savedInstanceState)
        initCommonEvents()

        initData()
        initEvents()
        initEvents(savedInstanceState)

    }

    private fun beforeLoadLayout() {

    }

    private fun initCommonEvents() {
        // 处理页面返回按钮点击事件
        findViewById<TitleBarView?>(R.id.titleBar)?.let {
            it.setOnLeftBtnClickListener { finish() }
        }

        // 初始化沉浸式状态栏
        if (isStatusBarEnabled()) {
            getStatusBarConfig().init()
            // 设置标题栏沉浸
            findViewById<View?>(R.id.rootLayout)?.let {
                ImmersionBar.setTitleBar(this, it)
            }
        }
    }

    override fun getBundle(): Bundle? {
        return intent.extras
    }

    open fun afterLoadLayout(savedInstanceState: Bundle?) {}
    open fun initData() {}
    open fun initEvents() {}
    open fun initEvents(savedInstanceState: Bundle?) {}
    abstract fun getLayoutResId(): Int

    /**
     * 供子类BaseVmActivity 初始化DataBinding操作
     */
    open fun initDataBinding() {}

    /**
     * 供子类BaseVmActivity 初始化ViewModel
     */
    open fun initViewModel() {}

    fun useDataBinding(isUseDB: Boolean) {
        this.isUseDB = isUseDB
    }

    //设置app字体不允许随系统调节而发生大小变化
    override fun getResources(): Resources? {
        val resources = super.getResources()
        val configuration = Configuration()
        configuration.setToDefaults()
        resources.updateConfiguration(configuration, resources.displayMetrics)
        return resources
    }

    /**
     * 点击空白处关闭软件盘
     */
    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_DOWN) {
            val v = currentFocus
            if (isShouldHideInput(v, ev)) {
                hideKeyboard(v)
            }
            return super.dispatchTouchEvent(ev)
        }
        return window.superDispatchTouchEvent(ev) || onTouchEvent(ev)
    }

    /**
     * 判断是否点击输入框内
     */
    open fun isShouldHideInput(
        v: View?,
        event: MotionEvent
    ): Boolean {
        if (v is EditText) {
            val leftTop = intArrayOf(0, 0)
            v.getLocationInWindow(leftTop)
            val left = leftTop[0]
            val top = leftTop[1]
            val bottom = top + v.getHeight()
            val right = left + v.getWidth()
            return (event.x <= left || event.x >= right
                    || event.y <= top || event.y >= bottom)
        }
        return false
    }

    override fun getContext(): Context {
        return this
    }

    override fun startActivity(intent: Intent) {
        return super<AppCompatActivity>.startActivity(intent)
    }

    /**
     * 显示加载(转圈)对话框
     */
    fun showLoading(
        message: String = "正在加载...",
        isCancelable: Boolean = false
    ) {
        if (!this::loadingDialogFragment.isInitialized) {
            loadingDialogFragment = LoadingDialogFragment.newInstance()
        }
        if (!loadingDialogFragment.isAdded) {
            loadingDialogFragment.show(supportFragmentManager, message, isCancelable)
        }
    }

    /**
     * 隐藏加载(转圈)对话框
     */
    fun hideLoading() {
        if (this::loadingDialogFragment.isInitialized) {
            loadingDialogFragment.dismissAllowingStateLoss()
        }
    }


    //------------------- startActivityForResult 封装


    @Suppress("deprecation")
    override fun startActivityForResult(intent: Intent, requestCode: Int, options: Bundle?) {
        // 隐藏软键，避免内存泄漏
        hideKeyboard(currentFocus)
        // 查看源码得知 startActivity 最终也会调用 startActivityForResult
        super.startActivityForResult(intent, requestCode, options)
    }

    /**
     * startActivityForResult 方法优化
     */
    open fun startActivityForResult(clazz: Class<out Activity>, callback: OnActivityCallback?) {
        startActivityForResult(Intent(this, clazz), null, callback)
    }

    open fun startActivityForResult(intent: Intent, callback: OnActivityCallback?) {
        startActivityForResult(intent, null, callback)
    }

    @Suppress("deprecation")
    open fun startActivityForResult(
        intent: Intent,
        options: Bundle?,
        callback: OnActivityCallback?
    ) {
        // 请求码必须在 2 的 16 次方以内
        val requestCode: Int = Random().nextInt(2.0.pow(16.0).toInt())
        activityCallbacks.put(requestCode, callback)
        startActivityForResult(intent, requestCode, options)
    }

    @Suppress("deprecation")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        var callback: OnActivityCallback?
        if ((activityCallbacks.get(requestCode).also { callback = it }) != null) {
            callback?.onActivityResult(resultCode, data)
            activityCallbacks.remove(requestCode)
            return
        }
        super.onActivityResult(requestCode, resultCode, data)
    }

    interface OnActivityCallback {

        /**
         * 结果回调
         *
         * @param resultCode        结果码
         * @param data              数据
         */
        fun onActivityResult(resultCode: Int, data: Intent?)
    }

    //------------------- status bar -------------

    /**
     * 是否使用沉浸式状态栏
     */
    open fun isStatusBarEnabled() = false

    /**
     * 是否使用黑色字体
     */
    open fun isStatusBarDarkFont() = false

    /**
     * 状态栏背景颜色
     */
    open fun getStatusBarBacColor() = R.color.color_primary
    /**
     * 导航栏背景颜色
     */
    open fun getNavigationBarBacColor() = R.color.color_primary

    /**
     * 获取状态栏沉浸的配置对象
     */
    open fun getStatusBarConfig(): ImmersionBar {
        if (immersionBar == null) {
            immersionBar = createStatusBarConfig()
        }
        return immersionBar!!
    }

    /** 状态栏沉浸 */
    private var immersionBar: ImmersionBar? = null

    /**
     * 初始化沉浸式状态栏
     */
    protected open fun createStatusBarConfig(): ImmersionBar {
        return ImmersionBar.with(this)
            .statusBarDarkFont(isStatusBarDarkFont()) // 指定状态栏字体是否深色，默认白色
            .statusBarColor(getStatusBarBacColor())  //状态栏颜色，不写默认透明色
            .navigationBarColor(getNavigationBarBacColor()) // 状态栏字体和导航栏内容自动变色，必须指定状态栏颜色和导航栏颜色才可以自动变色
//          .autoDarkModeEnable(true, 0.2f)
    }

}